package shitool

import (
	"fmt"
	"github.com/gogf/gf/crypto/gaes"
	"github.com/gogf/gf/encoding/gbase64"
	"github.com/gogf/gf/encoding/gcharset"
	"github.com/gogf/gf/encoding/gjson"
	"github.com/gogf/gf/encoding/gurl"
	"github.com/gogf/gf/errors/gerror"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/net/ghttp"
	"github.com/gogf/gf/os/gtime"
	"github.com/gogf/gf/text/gstr"
	"github.com/gogf/gf/util/gconv"
	"math"
	"net"
	"strconv"
	"strings"
	"time"
)

//字符串加密
func EncryptCBC(plainText, publicKey string) string {
	key := []byte(publicKey)
	b, e := gaes.EncryptCBC([]byte(plainText), key, key)
	if e != nil {
		g.Log().Error(e.Error())
		return ""
	}
	return gbase64.EncodeToString(b)
}

//字符串解密
func DecryptCBC(plainText, publicKey string) string {
	key := []byte(publicKey)
	plainTextByte, e := gbase64.DecodeString(plainText)
	if e != nil {
		g.Log().Error(e.Error())
		return ""
	}
	b, e := gaes.DecryptCBC(plainTextByte, key, key)
	if e != nil {
		g.Log().Error(e.Error())
		return ""
	}
	return gbase64.EncodeToString(b)
}

//服务端ip
func GetLocalIP() (ip string, err error) {
	addrs, err := net.InterfaceAddrs()
	if err != nil {
		return
	}
	for _, addr := range addrs {
		ipAddr, ok := addr.(*net.IPNet)
		if !ok {
			continue
		}
		if ipAddr.IP.IsLoopback() {
			continue
		}
		if !ipAddr.IP.IsGlobalUnicast() {
			continue
		}
		return ipAddr.IP.String(), nil
	}
	return
}

//获取客户端IP
func GetClientIp(r *ghttp.Request) string {
	ip := r.Header.Get("X-Forwarded-For")
	if ip == "" {
		ip = r.GetClientIp()
	}
	return ip
}

//获取相差时间
func GetHourDiffer(startTime, endTime string) int64 {
	var hour int64
	t1, err := time.ParseInLocation("2006-01-02 15:04:05", startTime, time.Local)
	t2, err := time.ParseInLocation("2006-01-02 15:04:05", endTime, time.Local)
	if err == nil && t1.Before(t2) {
		diff := t2.Unix() - t1.Unix() //
		hour = diff / 3600
		return hour
	} else {
		return hour
	}
}

//日期字符串转时间戳（秒）
func StrToTimestamp(dateStr string) int64 {
	tm, err := gtime.StrToTime(dateStr)
	if err != nil {
		g.Log().Error(err)
		return 0
	}
	return tm.Timestamp()
}

//时间戳转 yyyy-MM-dd HH:mm:ss
func TimeStampToDateTime(timeStamp int64) string {
	tm := gtime.NewFromTimeStamp(timeStamp)
	return tm.Format("Y-m-d H:i:s")
}

//时间戳转 yyyy-MM-dd
func TimeStampToDate(timeStamp int64) string {
	tm := gtime.NewFromTimeStamp(timeStamp)
	return tm.Format("Y-m-d")
}

//获取ip所属城市
func GetCityByIp(ip string) string {
	if ip == "" {
		return ""
	}
	if ip == "[::1]" || ip == "127.0.0.1" {
		return "内网IP"
	}
	url := "http://whois.pconline.com.cn/ipJson.jsp?json=true&ip=" + ip
	bytes := ghttp.GetBytes(url)
	src := string(bytes)
	srcCharset := "GBK"
	tmp, _ := gcharset.ToUTF8(srcCharset, src)
	json, err := gjson.DecodeToJson(tmp)
	if err != nil {
		return ""
	}
	if json.GetInt("code") == 0 {
		city := json.GetString("city")
		return city
	} else {
		return ""
	}
}

//获取附件真实路径
func GetRealFilesUrl(r *ghttp.Request, path string) (realPath string, err error) {
	if gstr.ContainsI(path, "http") {
		realPath = path
		return
	}
	realPath, err = GetDomain(r)
	if err != nil {
		return
	}
	realPath = realPath + path
	return
}

//获取当前请求接口域名
func GetDomain(r *ghttp.Request) (string, error) {
	pathInfo, err := gurl.ParseURL(r.GetUrl(), -1)
	if err != nil {
		g.Log().Error(err)
		err = gerror.New("解析附件路径失败")
		return "", err
	}
	return fmt.Sprintf("%s://%s:%s/", pathInfo["scheme"], pathInfo["host"], pathInfo["port"]), nil
}

//获取附件相对路径
func GetFilesPath(fileUrl string) (path string, err error) {
	if !gstr.ContainsI(fileUrl, "http") {
		path = fileUrl
		return
	}
	pathInfo, err := gurl.ParseURL(fileUrl, 32)
	if err != nil {
		g.Log().Error(err)
		err = gerror.New("解析附件路径失败")
		return
	}
	path = gstr.TrimLeft(pathInfo["path"], "/")
	return
}

//判断该时间戳到现在的年份
func TimesYear(date int64) int {
	berforeyear :=time.Unix(date, 0).Year()
	afteryear := time.Now().Year()
	return afteryear - berforeyear
}


//对”https://111.com , http://222.com“ 转换成数组
func StringToStrings (str string) []string{
	strsnew:=make([]string,0)
	if len(str)>0 {
		strs:=strings.Split(str,",")
		strsnew=strs
	}


	return strsnew
}
//对数组 转换成 ”https://111.com , http://222.com“
func StringsToString (strs []string) string{
	str:=""
	for _,v:=range strs{
		if str!="" {
			str += ","
		}
		str += v
	}

	return str
}


//对”https://111.com , http://222.com“ 转换成int数组
func IntToInts (str string) []int{
	strsnew:=make([]int,0)
	if len(str)>0 {
		strs:=strings.Split(str,",")
		strsnew=gconv.Ints(strs)
	}


	return strsnew
}
//对数组 转换成 ”https://111.com , http://222.com“
func IntsToInt (strs []int) string{
	str:=""
	for _,v:=range strs{
		if str!="" {
			str += ","
		}
		str += gconv.String(v)
	}
	str=strings.Replace(str,"[","",-1)
	str=strings.Replace(str,"]","",-1)
	return str
}

//取小数点
func FormatFloat(num float64, decimal int) string {
	// 默认乘1
	d := float64(1)
	if decimal > 0 {
		// 10的N次方
		d = math.Pow10(decimal)
	}
	// math.trunc作用就是返回浮点数的整数部分
	// 再除回去，小数点后无效的0也就不存在了
	return strconv.FormatFloat(math.Trunc(num*d)/d, 'f', -1, 64)
}

//取2位小数点 四舍五入
func FormatFloat64(num float64, decimal int) float64 {
	n10 := math.Pow10(decimal)
	num2 := math.Trunc((num+0.5/n10)*n10) / n10
	return num2
}

//取2位小数点 四舍五入 负数
func FormatFloat641(num float64, decimal int) float64 {
	n10 := math.Pow10(decimal)
	num2 := math.Trunc((num-0.5/n10)*n10) / n10
	return num2
}

//根据身份证获取年龄
func IdCardAge(idcard string) (age int){

	if len(idcard)>10 {
		year:=idcard[6:10]
		nowyear:=time.Now().Year()
		age=nowyear-gconv.Int(year)
	}
	if	len(idcard)!=18{
		age=0
	}

	return age
}

//输入俩时间得出天数，小时  t1:最早的时间  t2:最迟的时间  state 1 :day  2:hour
func CompeleteTime(t1 int64 ,t2 int64,state int) float64{
	t3:=t2-t1

	var res float64

	//天
	if state==1 {
		res=FormatFloat64(float64(t3)/60/60/24,2)
	}
	//小时
	if state==2 {
		res=FormatFloat64(float64(t3)/60/60,2)
	}

	return res
}
